package fr.lille.inria.adam.lifl.EcoGardeInventory.Activities;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.SectionIndexer;
import android.widget.TabHost;
import android.widget.TabHost.TabSpec;
import android.widget.TextView;
import fr.lille.inria.adam.lifl.EcoGardeInventory.R;
import fr.lille.inria.adam.lifl.EcoGardeInventory.Utils.EspeceEntry;
import fr.lille.inria.adam.lifl.EcoGardeInventory.Utils.StringListIndexer;
import fr.lille.inria.adam.lifl.EcoGardeInventory.Utils.sparse.SparseToArray;

public class SelectEspece extends BuildObservationActivity {
	protected ListView latinList;
	protected ListView commonList;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.select_espece);
		
		// #region Pr�partion de la barre d'onglets
		TabHost host = (TabHost) findViewById(R.id.especeTabHost);
		host.setup();
		TabSpec tSpec = host.newTabSpec("Commun");
		tSpec.setContent(R.id.layout_espece_commun);
		tSpec.setIndicator("Commun");
		host.addTab(tSpec);
		
		tSpec = host.newTabSpec("Latin");
		tSpec.setContent(R.id.layout_espece_latin);
		tSpec.setIndicator("Latin");
		host.addTab(tSpec);
		// #endregion
		// #region R�cup�ration des ListView et branchement du comportement
		commonList = (ListView) findViewById(R.id.listview_commun);
		latinList = (ListView) findViewById(R.id.listview_latin);
		commonList.setOnItemClickListener(buildOnEspeceClickedListener());
		latinList.setOnItemClickListener(buildOnEspeceClickedListener());
		// #endregion
	}
	
	/**Necessite que les ListView aient �t� r�cup�r�es et que la connexion au service soit OK
	 */
	private void alimenterLesListesEspeces() {
		SparseArray<EspeceEntry> especes = clientBinder.retrieveEspeces(observationEnCoursDeRealisation.groupeEspece);

		// #region On trie en 2 List
		ArrayList<EspeceEntry> sortedByCommun = SparseToArray.getValuesCollection(especes);
		Collections.sort(sortedByCommun, new Comparator<EspeceEntry>() {
			@Override
			public int compare(EspeceEntry lhs, EspeceEntry rhs) {
				return lhs.commun.compareToIgnoreCase(rhs.commun);
			}
		});
		
		ArrayList<EspeceEntry> sortedByLatin = SparseToArray.getValuesCollection(especes);
		Collections.sort(sortedByLatin, new Comparator<EspeceEntry>() {
			@Override
			public int compare(EspeceEntry lhs, EspeceEntry rhs) {
				return lhs.latin.compareToIgnoreCase(rhs.latin);
			}
		});
		// #endregion
		
		this.commonList.setAdapter(new EspeceEntryAdapter(
				getApplicationContext(), 
				R.id.especeListItem_main, 
				R.id.especeListItem_sub, 
				R.layout.espece_listitem, 
				sortedByCommun, new StringListIndexer(toCommonValues(sortedByCommun))));
		this.latinList.setAdapter(new EspeceEntryAdapter(
				getApplicationContext(), 
				R.id.especeListItem_sub, 
				R.id.especeListItem_main, 
				R.layout.espece_listitem, 
				sortedByLatin, new StringListIndexer(toLatinValues(sortedByLatin))));
	}
	
	@Override
	protected ServiceConnection initializeClientSIGServConn() {
		return new ServiceConnection() {
			
			@Override
			public void onServiceDisconnected(ComponentName name) { }
			
			@Override
			public void onServiceConnected(ComponentName name, IBinder service) {
				alimenterLesListesEspeces();
			}
		};
	}
	
	private OnItemClickListener buildOnEspeceClickedListener() {
		return new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				observationEnCoursDeRealisation.nomEspece = (int) id;
				startActivity(buildNextActivityIntent());
			}
		};
	}
	
	private Intent buildNextActivityIntent() {
		Intent result = new Intent(getApplicationContext(), QuantizePopulation.class);
		result.putExtra("SIG_OBSERVATION", observationEnCoursDeRealisation);
		result.putExtra("SIG_USER", user);
		return result;
	}
	
	/**Adapter qui permet de brancher des liste ordonn�e d'EspeceEntry � des ListView.
	 * Cet adapter requiere
	 * @author liabeuf
	 * @author android.widget.ArrayAdapter
	 */
	private class EspeceEntryAdapter extends BaseAdapter implements SectionIndexer {
		protected List<EspeceEntry> entries;
		private LayoutInflater mInflater;
		private SectionIndexer indexer;
		
	    private int latinFieldId = 0;
	    private int commonFieldId = 0;
	    
	    /**
	     * The resource indicating what views to inflate to display the content of this
	     * array adapter.
	     */
	    private int mLayoutId;
	    
	    
	    
	    /**
	     * Constructor
	     *
	     * @param context The current context.
	     * @param commonFieldId id du TextView pour le nom commun
	     * @param latinFieldId id du TextView pour le nom latin
	     * @param layouId The id of the layout
	     * @param objects The objects to represent in the ListView.
	     */
	    public EspeceEntryAdapter(Context context, 
	    		int commonFieldId, 
	    		int latinFieldId, int layouId, 
	    		List<EspeceEntry> objects,
	    		SectionIndexer indexer) {
	    	mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	        mLayoutId = layouId;
	        entries = objects;
	        this.latinFieldId=latinFieldId;
	        this.commonFieldId=commonFieldId;
	        this.indexer = indexer;
	    }

		@Override
		public int getCount() { return entries.size(); }

		@Override
		public Object getItem(int position) { return entries.get(position); }

		@Override
		public long getItemId(int position) { return entries.get(position).id; }
	    

	    /**
	     * {@inheritDoc}
	     */
	    public View getView(int position, View convertView, ViewGroup parent) {
	        return createViewFromResource(position, convertView, parent, mLayoutId);
	    }

	    private View createViewFromResource(int position, View convertView, ViewGroup parent, int resource) {
	        View view;
	        TextView latinText, commonText;

	        // Le r�sultat
	        if (convertView == null) {
	            view = mInflater.inflate(resource, parent, false);
	        } else {
	            view = convertView;
	        }

	        latinText = (TextView) view.findViewById(latinFieldId);
	        commonText = (TextView) view.findViewById(commonFieldId);
	        
	        EspeceEntry item = entries.get(position);
	        latinText.setText(item.latin);
	        commonText.setText(item.commun);

	        return view;
	    }

		@Override
		public int getPositionForSection(int section) { return indexer.getPositionForSection(section); }

		@Override
		public int getSectionForPosition(int position) { return indexer.getSectionForPosition(position); }
		
		@Override
		public Object[] getSections() { return indexer.getSections(); }
	}
	
	private static final ArrayList<String> toCommonValues(ArrayList<EspeceEntry> e) {
		ArrayList<String> result = new ArrayList<String>(e.size());
		for (EspeceEntry ee : e) {
			result.add(ee.commun);
		}
		return result;
	}
	
	private static final ArrayList<String> toLatinValues(ArrayList<EspeceEntry> e) {
		ArrayList<String> result = new ArrayList<String>(e.size());
		for (EspeceEntry ee : e) {
			result.add(ee.latin);
		}
		return result;
	}
}
